import { ElNotification } from 'element-plus';
import config from "@/config/config";
import { useUserStore } from '@/stores/userStore';
import { redirectToUserLogin } from '@/router/instuction';
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
import { ref } from 'vue';

interface DataMessage {
    sender: string;
    room: string;
    type: string;
    content: string;
}

let socket: WebSocket | null = null;
let stompClient: Stomp.Client | null = null;
let reconnectionTimer: number | undefined;
const MAX_RECONNECTION_ATTEMPTS = 3;
let reconnectionAttempts = 0;
let username: string | null = null;

const websocketService = {
    isConnected: ref(false),

    init() {
        try {
            const accessToken = localStorage.getItem("accessToken");
            const userStore = useUserStore();
            username = userStore.username;
            console.log("Init:" + username);
            console.log(accessToken);

            if (!username) {
                console.error("用户名未设置。");
                ElNotification.error({
                    title: '上线失败',
                    message: '请重新登录',
                    type: 'error',
                });
                return redirectToUserLogin();
            }

            socket = new SockJS(`${config.apiBaseUrl}/ws`);
            stompClient = Stomp.over(socket);
            stompClient.debug = (str) => {
                console.log('STOMP: ' + str);
            };

            // 在连接时传递用户名作为 STOMP 头
            stompClient.connect({ username: username }, (frame) => {
                console.log('连接成功:', frame);
                this.isConnected.value = stompClient.connected;
                this.onConnected();
            }, (error) => {
                console.log('连接错误:', error);
                this.onError(error);
            });

        } catch (error) {
            console.log(error);
        }
    },

    onConnected() {
        try {
            console.log("连接成功");
            ElNotification.success({
                title: `用户${username}`,
                message: '欢迎光临',
                type: 'success',
            });
            heartCheck.start();
        } catch (error) {
            console.log(error);
        }
    },

    onMessage(message: any) {
        let data = JSON.parse(message.body);
        console.log('收到的消息:', data);
        if (data.flag === 'message') {
            const event = new CustomEvent('message-received', { detail: data });
            window.dispatchEvent(event);
        }
    },

    onSub(address: string) {
        try {
            if (stompClient) {
                stompClient.subscribe(address, (message) => {
                    if (message.body) {
                        const data = JSON.parse(message.body);
                        console.log(data);
                        const event = new CustomEvent('message-received', { detail: data });
                        window.dispatchEvent(event);
                    }
                }, (error) => {
                    console.log('订阅失败:', error);
                });
            }
        } catch (error) {
            console.log(error);
        }
    },

    onError(error: any): void {
        console.log('连接失败: ', error);
        if (reconnectionAttempts < MAX_RECONNECTION_ATTEMPTS) {
            clearTimeout(reconnectionTimer);
            reconnectionTimer = window.setTimeout(() => {
                reconnectionAttempts++;
                this.init();
            }, 5000);
        } else {
            ElNotification.error({
                title: '连接失败',
                message: '无法连接到后端服务器',
                type: 'error',
            });
            localStorage.clear();
            redirectToUserLogin();
        }
    },

    onClose(event: any): void {
        console.log('连接关闭: ', event);
        if (reconnectionAttempts < MAX_RECONNECTION_ATTEMPTS) {
            clearTimeout(reconnectionTimer);
            reconnectionTimer = window.setTimeout(() => {
                reconnectionAttempts++;
                this.init();
            }, 5000);
        } else {
            ElNotification.error({
                title: '连接关闭',
                message: '与服务器的连接已关闭',
                type: 'error',
            });
            localStorage.clear();
            redirectToUserLogin();
        }
    },

    send(address: string, data: DataMessage): void {
        if (stompClient && stompClient.connected) {
            stompClient.send(address, {}, JSON.stringify(data));
        } else {
            console.error("STOMP client未连接。");
        }
    },

    close(): void {
        if (stompClient) {
            stompClient.disconnect(() => {
                console.log("断开连接");
            });
        }
        reconnectionAttempts = 0;
        clearTimeout(reconnectionTimer);
    }
};

export default websocketService;

// 心跳检测机制
const heartCheck = {
    timeout: 30000,  // 30秒
    timeoutObj: null as ReturnType<typeof setTimeout> | null,

    reset(): void {
        this.stop();
        this.start();
    },

    start(): void {
        if (stompClient && stompClient.connected) {
            this.timeoutObj = setTimeout(() => {
                console.log('发送心跳...');
                websocketService.send("/app/chatAll", {
                    sender: username!,
                    room: 'public',
                    type: 'heartbeat',
                    content: 'heartbeat'
                });
                this.reset();
            }, this.timeout);
        }
    },

    stop(): void {
        if (this.timeoutObj) {
            clearTimeout(this.timeoutObj);
            this.timeoutObj = null;
        }
    }
};
